package com.tmc.service.intair;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.tmc.bean.common.CommonResult;
import com.tmc.bean.common.ContextInfo;
import com.tmc.bean.common.Pagination;
import com.tmc.constant.FareConstant;
import com.tmc.constant.OrderConstant;
import com.tmc.constant.FareConstant.PolicyStatus;
import com.tmc.dao.impl.EthClientDaoImpl;
import com.tmc.dao.impl.TripartitePolicyDaoImpl;
import com.tmc.dao.impl.intair.IntairOrderDaoImpl;
import com.tmc.entity.common.EthClient;
import com.tmc.entity.intair.IntairFlight;
import com.tmc.entity.intair.IntairOrder;
import com.tmc.entity.intair.IntairSegment;
import com.tmc.entity.intair.TripartitePolicy;
import com.tmc.service.baseinfo.AirlineServiceImpl;
import com.tmc.service.baseinfo.AirportServiceImpl;
import com.tmc.service.baseinfo.ContinentServiceImpl;
import com.tmc.service.baseinfo.CountryServiceImpl;
import com.tmc.util.DateUtil;
import com.tmc.util.ObjectUtil;
import com.tmc.util.PolicyMatchUtil;
import com.tmc.util.PolicyUtil;

@Service
@Transactional
public class TripartitePolicyServiceImpl {
	
	private Log logger = LogFactory.getLog(TripartitePolicyServiceImpl.class);
	
	@Autowired
	private IntairOrderServiceImpl orderService;
	
	@Autowired
	private IntairOrderDaoImpl orderDao;
	
	@Autowired
	private TripartitePolicyDaoImpl policyDao;
	
	@Autowired
	private CountryServiceImpl countrySer;

	@Autowired
	private ContinentServiceImpl continentSer;

	@Autowired
	private AirportServiceImpl airportSer;

	@Autowired
	private AirlineServiceImpl airlineSer;
	
	@Autowired
	private EthClientDaoImpl clientDao;
	
	
	public Pagination<TripartitePolicy> findByCond(ContextInfo context, TripartitePolicy cond, Integer pageIndex, Integer pageSize){
		Pagination<TripartitePolicy> result = policyDao.findByCon(context, cond, pageIndex, pageSize);		
		this.setExtInfo(result.getItems());
		this.beforeShow(result.getItems());
		return result;	
	}
	
	public CommonResult savePolicy(ContextInfo context, TripartitePolicy policy){
		CommonResult check = this.checkPolicy(context, policy);
		if (!check.isSuccess()) {
			return check;
		}
		this.beforeSave(policy);
		
		if(policy.getPolicyId() == null){
			try{
				ObjectUtil.setBaseInfo(policy, context);
				policy.setStatus(PolicyStatus.DOWN.getStatus());
				policyDao.insert(policy);
			}catch(Exception e){
				logger.error("保存政策失败！", e);
				return CommonResult.makeFail(e.getMessage());
			}
		}else{
			try {
			TripartitePolicy dbPolicy = policyDao.getById(policy.getPolicyId());
				if (dbPolicy != null) {
					ObjectUtil.copyProperties(policy, dbPolicy,
							new String[] { "createdBy", "creationDate", "policyId", "status", "enabledFlag" });
				}
				ObjectUtil.updateBaseInfo(dbPolicy, context);
				policyDao.update(dbPolicy);
			} catch (Exception e) {
				logger.error("保存政策失败！", e);
				return CommonResult.makeFail("保存政策失败！");				
			}		
		}
		return CommonResult.makeSuccess("保存政策成功！");	
	}
	
	public CommonResult changePolicyStatus(ContextInfo context, Long policyId, String toStatus) {
		TripartitePolicy policy = policyDao.getById(policyId);
		if (policy != null) {
			ObjectUtil.updateBaseInfo(policy, context);
			policy.setStatus(toStatus);
			policyDao.update(policy);
		}
		return CommonResult.makeSuccess();
	}

	public CommonResult changePolicysStatus(ContextInfo context, String policyIds, String toStatus) {
		if (ObjectUtil.noText(policyIds)) {
			return CommonResult.makeFail("请选择至少一条政策");
		}
		for (String policyId : policyIds.split(",")) {
			this.changePolicyStatus(context, Long.valueOf(policyId), toStatus);
		}
		return CommonResult.makeSuccess();
	}
	
	public CommonResult deletePolicy(ContextInfo context, Long policyId) {
		TripartitePolicy policy = policyDao.getById(policyId);
		if (policy != null) {
			ObjectUtil.updateBaseInfo(policy, context);
			policy.setEnabledFlag("N");
			policyDao.update(policy);
		}
		return CommonResult.makeSuccess("删除成功！");
	}

	public CommonResult deletePolicys(ContextInfo context, String policyIds) {
		if (!ObjectUtil.hasText(policyIds)) {
			return CommonResult.makeSuccess();
		}
		for (String str : policyIds.split(",")) {
			CommonResult cr = this.deletePolicy(context, Long.valueOf(str));
			if (!cr.isSuccess()) {
				return cr;
			}
		}
		return CommonResult.makeSuccess("删除成功！");
	}
	
	public TripartitePolicy copyPolicy(ContextInfo context, Long policyId) {
		TripartitePolicy dbPolicy = policyDao.getById(policyId);
		TripartitePolicy policy = new TripartitePolicy();
		try {
			if(dbPolicy != null){
				ObjectUtil.copyProperties(dbPolicy,policy,
						new String[] { "createdBy", "creationDate", "status", "policyId", "enabledFlag" });
			}
			policy.setSourcePolicyId(dbPolicy.getPolicyId());
			this.beforeShow(policy);
		} catch (Exception e) {
			logger.error("复制政策失败！", e);
		}
		return policy;
	}

	
	public TripartitePolicy getById(ContextInfo context, Long policyId){
		return policyDao.getById(policyId);	
	}
	
	public TripartitePolicy getById4Show(ContextInfo context,Long policyId){
		TripartitePolicy policy = policyDao.getById(policyId);
		this.setExtInfo(policy);
		this.beforeShow(policy);
		return policy;	
	}
	
	private void setExtInfo(List<TripartitePolicy> policys){
		if(policys == null || policys.isEmpty()){
			return;
		}
		for (TripartitePolicy policy : policys) {
			this.setExtInfo(policy);
		}
	}
	
	private void setExtInfo(TripartitePolicy policy) {
		if(policy == null){
			return;
		}
		EthClient dbClient = clientDao.getById(policy.getClientId());
		if(dbClient != null){
			policy.setClientAddress(dbClient.getAddress());
		}
		this.beforeShow(policy);
	}

	private void beforeShow(List<TripartitePolicy> policys){
		if(policys == null || policys.isEmpty()){
			return;
		}
		for (TripartitePolicy policy : policys) {
			this.beforeShow(policy);
		}
	}
	

	
	private void beforeShow(TripartitePolicy policy){
		if(policy == null){
			return;
		}
		policy.setFlightTypeName(PolicyUtil.getFlightTypeName(policy.getFlightType()));
		policy.setDepartureName(this.getAreaNames(policy.getDeparture()));
		policy.setArrivalName(this.getAreaNames(policy.getArrival()));
		policy.setAirlineName(airlineSer.getNameByCode(policy.getAirline()));
		policy.setStatusName(FareConstant.getStatusName(policy.getStatus()));
		policy.setAutoTicketingFlagName(PolicyUtil.getTrueOrFalseName(policy.getAutoTicketingFlag()));
		try {
			policy.setFlightDateStartStr(DateUtil.toStrDate(policy.getFlightDateStart(), "yyyy-MM-dd"));
			policy.setFlightDateEndStr(DateUtil.toStrDate(policy.getFlightDateEnd(), "yyyy-MM-dd"));		
			policy.setProtocolDateEndStr(DateUtil.toStrDate(policy.getProtocolDateEnd(), "yyyy-MM-dd"));
			policy.setProtocolDateStartStr(DateUtil.toStrDate(policy.getProtocolDateStart(), "yyyy-MM-dd"));
			policy.setTicketingDateStartStr(DateUtil.toStrDate(policy.getTicketingDateStart(), "yyyy-MM-dd"));
			policy.setTicketingDateEndStr(DateUtil.toStrDate(policy.getTicketingDateEnd(), "yyyy-MM-dd"));
			if(policy.getFlightDateExcludeStart() != null){
				policy.setFlightDateExcludeStartStr(DateUtil.toStrDate(policy.getFlightDateExcludeStart(), "yyyy-MM-dd"));
			}
			if(policy.getFlightDateExcludeEnd() != null){
				policy.setFlightDateExcludeEndStr(DateUtil.toStrDate(policy.getFlightDateExcludeEnd(), "yyyy-MM-dd"));
			}
		} catch (ParseException e) {
		}
	}
	
	private void beforeSave(TripartitePolicy policy) {
		if (!"Y".equals(policy.getAutoTicketingFlag())){
			policy.setAutoTicketingFlag("N");
		}
		if (!"Y".equals(policy.getAutoFlightShareFlag())){
			policy.setAutoFlightShareFlag("N");
		}
		if (!"Y".equals(policy.getBaseCommisionFlag())){
			policy.setBaseCommisionFlag("N");
		}
		policy.setFlightDateStart(DateUtil.toLongDate(policy.getFlightDateStartStr(), "yyyy-MM-dd"));
		policy.setFlightDateEnd(DateUtil.toLongDate(policy.getFlightDateEndStr(), "yyyy-MM-dd"));
		policy.setProtocolDateStart(DateUtil.toLongDate(policy.getProtocolDateStartStr(), "yyyy-MM-dd"));
		policy.setProtocolDateEnd(DateUtil.toLongDate(policy.getProtocolDateEndStr(), "yyyy-MM-dd"));
		policy.setTicketingDateStart(DateUtil.toLongDate(policy.getTicketingDateStartStr(), "yyyy-MM-dd"));
		policy.setTicketingDateEnd(DateUtil.toLongDate(policy.getTicketingDateEndStr(), "yyyy-MM-dd"));
		if(ObjectUtil.hasText(policy.getFlightDateExcludeStartStr())){
			policy.setFlightDateExcludeStart(DateUtil.toLongDate(policy.getFlightDateExcludeStartStr(), "yyyy-MM-dd"));
		}
		if(ObjectUtil.hasText(policy.getFlightDateExcludeEndStr())){
			policy.setFlightDateExcludeEnd(DateUtil.toLongDate(policy.getFlightDateExcludeEndStr(), "yyyy-MM-dd"));
		}
		policy.setDeparture(getSpecialArea(policy.getDeparture()));
		policy.setArrival(getSpecialArea(policy.getArrival()));
		policy.setTransfer(getSpecialArea(policy.getTransfer()));
	}
	
	private String getSpecialArea(String area) {
		return area.replace("中国境内", "CN0").replace("境外", "CN1").replace("全球", "A00");
	}
	
	private String getAreaNames(String areas) {
		if (ObjectUtil.noText(areas)) {
			return "";
		}
		StringBuffer sb = new StringBuffer();
		for (String area : areas.split("/")) {
			if (ObjectUtil.noText(area)) {
				continue;
			}
			String areaName = this.getAreaName(area);
			if (sb.indexOf(areaName + "/") > -1){
				continue;
			}
			sb.append(areaName).append("/");
		}
		return sb.toString();
	}

	private String getAreaName(String area) {
		if ("CN0".equals(area)) {
			return "中国境内";
		}
		if ("CN1".equals(area)) {
			return "境外";
		}
		if ("A00".equals(area)) {
			return "全球";
		}
		if (area.length() == 2) {
			return countrySer.getNameByCode(area);
		}
		if (area.length() == 3) {
			return airportSer.getCityNameByCode(area);
		}
		if (area.length() == 4) {
			return continentSer.getNameByCode(area);
		}
		return area;
	}
	
	public CommonResult checkPolicy(ContextInfo context, TripartitePolicy policy){
		return CommonResult.makeSuccess();		
	}
	
	public CommonResult matchNativePolicy(ContextInfo context,Long orderId) {
		IntairOrder dbOrder = orderService.getById(context, orderId);
		if(dbOrder == null){
			return CommonResult.makeFail("订单出错!");
		}
		TripartitePolicy cond = new TripartitePolicy();
		if(!this.setSearchCond(cond, dbOrder)){
			return CommonResult.makeFail("未匹配到政策");
		}
		List<TripartitePolicy> policys = new ArrayList<TripartitePolicy>();//返回结果
		if (dbOrder.getFlightType().equals(OrderConstant.FLIGHT_TYPE_RT)) {// 往返订单
			List<TripartitePolicy> dbPolicysRT = policyDao.findListByPolicy(context, cond);			
			this.isMatchRtPolicys(dbOrder, policys, dbPolicysRT);//匹配往返订单的政策
		}else{// 单程订单
			
		}
		this.sortPolicys(policys);
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("order", dbOrder);
		map.put("policys", policys);
		return CommonResult.makeSuccess("", map);
	}
	
	
	
	private void isMatchRtPolicys(IntairOrder dbOrder, List<TripartitePolicy> policys,
			List<TripartitePolicy> dbPolicysRT) {
		// TODO Auto-generated method stub
		
	}

	private boolean setSearchCond(TripartitePolicy policy, IntairOrder dbOrder){
		//匹配单程或往返
		if(ObjectUtil.noText(dbOrder.getFlightType()) || 
				dbOrder.getFlightType().equals(OrderConstant.FLIGHT_TYPE_UN) ||
					dbOrder.getFlightType().equals(OrderConstant.FLIGHT_TYPE_MU)){
			return false;
		}else{
			policy.setFlightType(dbOrder.getFlightType().equals(OrderConstant.FLIGHT_TYPE_OW) ? "OW":"RT");
		}
		//匹配office号
		policy.setOfficeNo(dbOrder.getOfficeNo());
		//匹配出票方式
		policy.setAutoTicketingFlag(dbOrder.getTicketingType() == 1 ? "Y":"N");
		//政策状态为  UP
		policy.setStatus(PolicyStatus.UP.getStatus());
		return true;
	}
	
	private void sortPolicys(List<TripartitePolicy> policys) {
		if (policys == null || policys.isEmpty()) {
			return;
		}
		Collections.sort(policys, new Comparator<TripartitePolicy>() {
			@Override
			public int compare(TripartitePolicy c1, TripartitePolicy c2) {
				if (c1.getTotalAmount() < c2.getTotalAmount()) {
					return -1;
				} else if (c1.getTotalAmount() > c2.getTotalAmount()) {
					return 1;
				}
				return 0;
			}
		});
	}
	
	public void matchPolicy(List<IntairOrder> orders, List<TripartitePolicy> policys){
		if(orders == null || orders.isEmpty() || policys == null || policys.isEmpty()){
			return;
		}
		for (IntairOrder order : orders) {
			for (TripartitePolicy policy : policys) {
				if(!this.isMatch(order, policy)){
					continue;
				}
				// 关联order 和 policy ，进行更新操作
				order.setTripartitePolicyId(policy.getPolicyId());
				//设置季度信息
				if(policy.getAirline().equals("CZ")){
					try {
						Long bookDate = order.getBookDate();
						Long protocolDateStart = policy.getProtocolDateStart();
						order.setQuarter(this.getQuarter(bookDate,protocolDateStart));
					} catch (ParseException e) {
						logger.error("时间转换出错",e);
					}
				}
				ObjectUtil.updateBaseInfo(order, new ContextInfo());
				orderDao.update(order);
				break;
			}
		}
	}

	private String getQuarter(Long bookDate, Long protocolDateStart) throws ParseException {
		if(bookDate == null || bookDate == 0 || protocolDateStart == null || protocolDateStart == 0){
			return null;
		}
		Date dateStart = DateUtil.format(DateUtil.toStrDate(protocolDateStart, DateUtil.yyyyMMddHHmmss));
		DateUtil.addMonth(dateStart, 3);
		//Long dateStart = DateUtil.toLongDate(DateUtil.addMonth(date1, 3), DateUtil.yyyyMMddHHmmss);
		if (bookDate < (DateUtil.toLongDate(DateUtil.addMonth(dateStart, 3), DateUtil.yyyyMMddHHmmss)
				+ DateUtil.Day2Long)) {//第一季度
			return "1";
		} else if (bookDate < (DateUtil.toLongDate(DateUtil.addMonth(dateStart, 6), DateUtil.yyyyMMddHHmmss)
				+ DateUtil.Day2Long)) {//第二季度
			return "2";
		} else if (bookDate < (DateUtil.toLongDate(DateUtil.addMonth(dateStart, 9), DateUtil.yyyyMMddHHmmss)
				+ DateUtil.Day2Long)) {//第三季度
			return "3";
		} else if (bookDate < (DateUtil.toLongDate(DateUtil.addMonth(dateStart, 12), DateUtil.yyyyMMddHHmmss)
				+ DateUtil.Day2Long)) {//第四季度
			return "4";
		}
		return null;
	}

	private boolean isMatch(IntairOrder order, TripartitePolicy policy) {
		if(order == null || policy == null){
			return false;
		}
		String flightType = "OW";
		if (order.getFlightType().equals(OrderConstant.FLIGHT_TYPE_RT)) {
			flightType = "RT";
		}
		
		if(flightType.equals("RT")){
			// 匹配行程类型
			if (!PolicyMatchUtil.isFlightTypeMatch(policy.getFlightType(), flightType)) {
				return false;
			}
			// 匹配主逻辑
			if(!this.isMatch(policy, order, order.getFlights().get(0))){
				return false;
			}
			if(!this.isMatch(policy, order, order.getFlights().get(1))){
				return false;
			}
		} else if(flightType.equals("OW")){
			// 匹配行程类型
			if (!PolicyMatchUtil.isFlightTypeMatch(policy.getFlightType(), flightType)) {
				return false;
			}
			//匹配主逻辑
			if(!this.isMatch(policy, order, order.getFlights().get(0))){
				return false;
			}
			
		}
		return true;
	}

	private boolean isMatch(TripartitePolicy policy, IntairOrder order, IntairFlight flight) {
		//匹配客户
		if(!PolicyMatchUtil.isClientMatch(policy.getClientId(), order.getClientId())){
			return false;
		}
		//匹配officeNo
		if(!PolicyMatchUtil.isOfficeNoMatch(policy.getOfficeNo(), order.getOfficeNo())){
			return false;
		}
		// 相关时间是否匹配
		if (!PolicyMatchUtil.isDateMatch(policy, order, flight)) {
			return false;
		}

		// 中转地是否匹配
		if (!PolicyMatchUtil.isTransferMatch(flight.getTransfer(),
				airportSer.getCountryCodeByCode(flight.getTransfer()), policy.getTransfer(),
				policy.getTransferExclude())) {// 匹配中转地
			return false;
		}
		if (order.getFlights().get(0) == flight) {// 去程
			// 匹配去程的出发地和到达地位
			if (!PolicyMatchUtil.isDirectMatch(flight.getDeparture(),
					airportSer.getCountryCodeByCode(flight.getDeparture()), flight.getArrival(),
					airportSer.getCountryCodeByCode(flight.getArrival()), policy)) {//
				return false;
			}
			// 匹配去程的舱位
			if (!PolicyMatchUtil.isCabinMatch(flight, policy.getDepartureCabins(), policy.getTransferCabins())) {
				return false;
			}

		} else { // 返程
			// 匹配返程的出发地和到达地位
			if (!PolicyMatchUtil.isDirectMatch(flight.getArrival(),
					airportSer.getCountryCodeByCode(flight.getArrival()), flight.getDeparture(),
					airportSer.getCountryCodeByCode(flight.getDeparture()), policy)) {//
				return false;
			}
			// 匹配返程的舱位
			if (!PolicyMatchUtil.isCabinMatch(flight, policy.getTransferCabins(), policy.getDepartureCabins())) {
				return false;
			}
		}
		for (IntairSegment segment : flight.getSegments()) {
			// 匹配适用的航班和航线
			if (!PolicyMatchUtil.isflightNoMatch(segment.getAirline(), segment.getFlightNo(), policy)) {
				return false;
			}
			// 航司是否匹配
			if (!PolicyMatchUtil.isAirlineMatch(segment.getAirline(), policy.getAirline(), policy.getAirlineShare())) {
				return false;
			}
		}
		return true;
	}
	
}
